namespace Nico{
    public enum Messages {
        HELO   = 0x1,
        INIT   = 0x2,
        CREATE = 0x3,
        UPDATE = 0x4,
        ACK    = 0x5,
        NACK   = 0x6
    }

	public class Resources  : GLib.Object {
		public bool tabak {get; set; default=false;}
		public bool filter {get; set; default=false;}
		public bool papes {get; set; default=false;}
		public bool lighter {get; set; default=false;}
	}
	public class Session  : GLib.Object {
		public int id {get; set; default=0;}
		public string[] users {get;set;}
		public string datetime{get; set; default="";}
		public string location {get; set; default="";}
		public Resources resources {get; set;}

        public Session() {
            this.users = new string[0];
            this.resources = new Resources();
        }

        public bool add_user(string user) {
            bool found = false;
            var narr = new string[this.users.length+1];
            uint i = 0;
            foreach (var u in this.users) {
                narr[i++] = u;
                if (u == user)
                    found = true;
            }
            if (found)
                return false;
            narr[this.users.length] = user;
            this.users = narr;
            return true;
        }

        public bool remove_user(string user) {
            bool found = false;
            var narr = new string[this.users.length-1];
            uint i = 0;
            foreach (var u in this.users) {
                if (u != user) {
                    narr[i++] = u;
                } else {
                    found = true;
                }
            }
            if (!found)
                return false;
            this.users = narr;
            return true;
        }
	}
	public class Ack  : GLib.Object {
		public int session_id {get; set; default=0;}
		public Resources resources {get; set;}
	}
	public class Nack  : GLib.Object {
		public int session_id {get; set; default=0;}
	}
	public class Helo  : GLib.Object {
		public string username {get; set; default="";}
	}

	public class Init  : GLib.Object {
		public Session[] sessions {get; set;}
		public string[] locations {get; set;}

        public Init() {}

        public string serialize() {
            var node = new Json.Node(Json.NodeType.ARRAY);
            var array = new Json.Array();
            foreach (var s in sessions) {
                var object = Json.gobject_serialize(s);
                array.add_element(object);
            }
            node.set_array(array);
            var selfnode = Json.gobject_serialize(this);
            var o = selfnode.get_object();
            o.set_member("sessions",node);
            
            var gen = new Json.Generator();
            gen.set_root(selfnode);
            return gen.to_data(null);
        }

        public static Init deserialize(string data) {
			var node = Json.from_string(data);
            Init init = (Init)Json.gobject_deserialize(typeof(Init), node);
            var sessions = new Array<Session>();
			node.get_object().get_member("sessions").get_array().foreach_element((_,i,e)=>{
                var session = (Session)Json.gobject_deserialize(typeof(Session), e);
				sessions.append_val(session);
            });
            init.sessions = sessions.data;
            return init;
        }
	}
}
